package com.xbongbong.saas.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.lfasr.util.StringUtil;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.wrap.BaseDTO;
import com.xbongbong.pro.enums.ErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.TemplateCenterErrorCodeEnum;
import com.xbongbong.pro.logistics.pojo.dto.ElectronicExpressSaveDTO;
import com.xbongbong.pro.logistics.pojo.dto.ExpressInformationSaveDTO;
import com.xbongbong.pro.logistics.pojo.dto.ExpressPrintTemplateSaveDTO;
import com.xbongbong.pro.logistics.pojo.dto.PrinterSaveDTO;
import com.xbongbong.pro.logistics.pojo.vo.ElectronicExressVO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.domain.entity.DataDictionaryEntity;
import com.xbongbong.saas.domain.entity.ExpressAccountEntity;
import com.xbongbong.saas.domain.entity.ExpressInformationEntity;
import com.xbongbong.saas.domain.entity.ExpressPrintTemplateEntity;
import com.xbongbong.saas.domain.entity.PrinterEntity;
import com.xbongbong.saas.domain.entity.ext.ExpressAccountExt;
import com.xbongbong.saas.domain.entity.ext.ExpressInformationExt;
import com.xbongbong.saas.domain.entity.ext.ExpressPrintTemplateExt;
import com.xbongbong.saas.domain.entity.ext.PrinterExt;
import com.xbongbong.saas.enums.business.ExpressCodeEnum;
import com.xbongbong.saas.enums.dictionary.DictionaryEnum;
import com.xbongbong.saas.model.DataDictionaryModel;
import com.xbongbong.saas.model.ExpressAccountModel;
import com.xbongbong.saas.model.ExpressInformationModel;
import com.xbongbong.saas.model.ExpressPrintTemplateModel;
import com.xbongbong.saas.model.PrinterModel;
import com.xbongbong.saas.service.ElectronicExpressService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Service("electronicExpressService")
public class ElectronicExpressServiceImpl implements ElectronicExpressService {
    @Resource
    private ExpressAccountModel expressAccountModel;
    @Resource
    private ExpressInformationModel expressInformationModel;
    @Resource
    private ExpressPrintTemplateModel expressPrintTemplateModel;
    @Resource
    private PrinterModel printerModel;
    @Resource
    private DataDictionaryModel dataDictionaryModel;

    /**
     * 电子面单页数据获取
     * @param baseDTO
     * @return
     * @throws XbbException
     */
    @Override
    public ElectronicExressVO getElectronicExpress(BaseDTO baseDTO) throws XbbException {
        ElectronicExressVO electronicExressVO = new ElectronicExressVO();
        String corpid = baseDTO.getCorpid();
        //快递100账号信息
        Map<String , Object> param = new HashMap<>();
        param.put(ParameterConstant.CORPID, corpid);
        param.put(ParameterConstant.DEL, BasicConstant.ZERO);
        List<ExpressAccountEntity> expressAccountEntities = expressAccountModel.findEntities(param);
        if (CollectionsUtil.isNotEmpty(expressAccountEntities)) {
            ExpressAccountExt expressAccountExt = new ExpressAccountExt();
            expressAccountExt.setDataId(expressAccountEntities.get(0).getId());
            ExpressAccountEntity expressAccountEntity = expressAccountEntities.get(0);
            BeanUtil.copyProperties(expressAccountEntity, expressAccountExt);
            electronicExressVO.setExpressAccountExt(expressAccountExt);
        }else {
            electronicExressVO.setExpressAccountExt(new ExpressAccountExt());
        }
        //快递公司信息
        List<ExpressInformationEntity> expressInformationEntities = expressInformationModel.findEntities(param);
        List<ExpressInformationExt> expressInformationExtList = new ArrayList<>();
        for (ExpressInformationEntity expressInformationEntity : expressInformationEntities) {
            ExpressInformationExt expressInformationExt = new ExpressInformationExt();
            BeanUtil.copyProperties(expressInformationEntity, expressInformationExt);
            expressInformationExt.setDataId(expressInformationEntity.getId());
            expressInformationExtList.add(expressInformationExt);
        }
        electronicExressVO.setExpressCorpList(expressInformationExtList);
        //打印模版信息
        List<ExpressPrintTemplateEntity> expressPrintTemplateEntities = expressPrintTemplateModel.findEntities(param);
        List<ExpressPrintTemplateExt> expressPrintTemplateExtList = new ArrayList<>();
        for (ExpressPrintTemplateEntity expressPrintTemplateEntity : expressPrintTemplateEntities) {
            ExpressPrintTemplateExt expressPrintTemplateExt = new ExpressPrintTemplateExt();
            BeanUtil.copyProperties(expressPrintTemplateEntity, expressPrintTemplateExt);
            expressPrintTemplateExt.setDataId(expressPrintTemplateEntity.getId());
            expressPrintTemplateExtList.add(expressPrintTemplateExt);
        }
        electronicExressVO.setExpressPrintTemplateList(expressPrintTemplateExtList);
        //打印机信息
        List<PrinterEntity> printerEntities = printerModel.findEntities(param);
        List<PrinterExt> printerExtList = new ArrayList<>();
        for (PrinterEntity printerEntity : printerEntities) {
            PrinterExt printerExt = new PrinterExt();
            BeanUtil.copyProperties(printerEntity, printerExt);
            printerExt.setDataId(printerEntity.getId());
            printerExtList.add(printerExt);
        }
        electronicExressVO.setPrinterExtList(printerExtList);
        Map<String, String> expressCodeMap = ExpressCodeEnum.getAllEnum();
        electronicExressVO.setExpressCodeMap(expressCodeMap);
        return electronicExressVO;
    }

    //电子面单数据保存
    @Override
    public ElectronicExressVO saveElectronicExpress(ElectronicExpressSaveDTO electronicExpressSaveDTO) throws XbbException {
        String corpid = electronicExpressSaveDTO.getCorpid();
        String userId = electronicExpressSaveDTO.getUserId();
        //快递100账号信息实体
        ExpressAccountExt expressAccountExt = electronicExpressSaveDTO.getExpressAccountExt();
        //快递公司信息
        List<ExpressInformationSaveDTO> expressInformationSaveDTOList = electronicExpressSaveDTO.getExpressInformationSaveDTOList();
        //打印模版信息
        List<ExpressPrintTemplateSaveDTO> expressPrintTemplateSaveDTOList = electronicExpressSaveDTO.getExpressPrintTemplateSaveDTOList();
        //打印机信息
        List<PrinterSaveDTO> printerSaveDTOList = electronicExpressSaveDTO.getPrinterSaveDTOList();
        ////快递100账号信息
        Long expressAccountId = expressAccountExt.getDataId();
        String accountKey = expressAccountExt.getAccountKey();
        String secret = expressAccountExt.getSecret();
        String customer = expressAccountExt.getCustomer();
        if (StringUtil.isEmpty(accountKey) || StringUtil.isEmpty(secret) || StringUtil.isEmpty(customer)
                || accountKey.length() > 100 || secret.length() > 100 || customer.length() > 100) {
            throw new XbbException(TemplateCenterErrorCodeEnum.API_ERROR_402007);
        }
        //账号信息的编辑保存

        //账号信息都为空时 该公司的账号del都置为0
        ExpressAccountEntity expressAccountEntity = new ExpressAccountEntity();
        expressAccountEntity.setCorpid(corpid);
        expressAccountEntity.setCreatorId(userId);
        expressAccountEntity.setAccountKey(accountKey);
        expressAccountEntity.setSecret(secret);
        expressAccountEntity.setCustomer(customer);
        expressAccountEntity.setAddTime(DateTimeUtil.getInt());
        expressAccountEntity.setUpdateTime(DateTimeUtil.getInt());
        expressAccountEntity.setDel(BasicConstant.ZERO);
        //新建
        if (Objects.isNull(expressAccountId) || Objects.equals(expressAccountId, 0L)){
            expressAccountModel.insert(expressAccountEntity);
        }else {
            //编辑更新
            expressAccountEntity.setId(expressAccountId);
            expressAccountModel.update(expressAccountEntity);
        }

        //快递公司信息的编辑保存
        if (Objects.nonNull(expressInformationSaveDTOList)){
            List<ExpressInformationEntity> insertList = new ArrayList<>();
            List<ExpressInformationEntity> updateList = new ArrayList<>();
            for (ExpressInformationSaveDTO expressInformationSaveDTO : expressInformationSaveDTOList) {
                Long dataId = expressInformationSaveDTO.getDataId();
                if (Objects.isNull(dataId) || Objects.equals(0L, dataId)){
                    ExpressInformationEntity expressInformationEntity = new ExpressInformationEntity();
                    expressInformationEntity.setCorpid(corpid);
                    expressInformationEntity.setExpressName(expressInformationSaveDTO.getExpressName());
                    expressInformationEntity.setExpressCode(expressInformationSaveDTO.getExpressCode());
                    expressInformationEntity.setPartentId(expressInformationSaveDTO.getPartentId());
                    expressInformationEntity.setPartentKey(expressInformationSaveDTO.getPartentKey());
                    expressInformationEntity.setPartentSecret(expressInformationSaveDTO.getPartentSecret());
                    expressInformationEntity.setPartentName(expressInformationSaveDTO.getPartentName());
                    expressInformationEntity.setNet(expressInformationSaveDTO.getNet());
                    expressInformationEntity.setCode(expressInformationSaveDTO.getCode());
                    expressInformationEntity.setCheckMan(expressInformationSaveDTO.getCheckMan());
                    expressInformationEntity.setCreatorId(userId);
                    expressInformationEntity.setAddTime(DateTimeUtil.getInt());
                    expressInformationEntity.setUpdateTime(DateTimeUtil.getInt());
                    expressInformationEntity.setDel(BasicConstant.ZERO);
                    insertList.add(expressInformationEntity);
                }else {
                    ExpressInformationEntity expressInformationEntity = new ExpressInformationEntity();
                    expressInformationEntity.setId(dataId);
                    expressInformationEntity.setExpressName(expressInformationSaveDTO.getExpressName());
                    expressInformationEntity.setExpressCode(expressInformationSaveDTO.getExpressCode());
                    expressInformationEntity.setPartentId(expressInformationSaveDTO.getPartentId());
                    expressInformationEntity.setPartentKey(expressInformationSaveDTO.getPartentKey());
                    expressInformationEntity.setPartentSecret(expressInformationSaveDTO.getPartentSecret());
                    expressInformationEntity.setPartentName(expressInformationSaveDTO.getPartentName());
                    expressInformationEntity.setNet(expressInformationSaveDTO.getNet());
                    expressInformationEntity.setCode(expressInformationSaveDTO.getCode());
                    expressInformationEntity.setCheckMan(expressInformationSaveDTO.getCheckMan());
                    expressInformationEntity.setCreatorId(userId);
                    expressInformationEntity.setUpdateTime(DateTimeUtil.getInt());
                    expressInformationEntity.setDel(BasicConstant.ZERO);
                    updateList.add(expressInformationEntity);
                }
            }
            if (!insertList.isEmpty()){
                expressInformationModel.insertBatch(insertList);
            }
            if (!updateList.isEmpty()){
                expressInformationModel.updateBatch(updateList,corpid);
            }
        }

        //打印模版的编辑保存
        Map<String, Object> param = new HashMap<>();
        param.put(ParameterConstant.CORPID, corpid);
        param.put(ParameterConstant.DEL, BasicConstant.ZERO);
        if (Objects.nonNull(expressPrintTemplateSaveDTOList)){
            List<ExpressPrintTemplateEntity> insertList = new ArrayList<>();
            List<ExpressPrintTemplateEntity> updateList = new ArrayList<>();
            //该公司下已有的打印机信息
            List<ExpressPrintTemplateEntity> entities = expressPrintTemplateModel.findEntities(param);
            List<Long> databaseIdList = new ArrayList<>();
            List<Long> saveTemplateIdList = new ArrayList<>();
            for (ExpressPrintTemplateEntity entity : entities) {
                databaseIdList.add(entity.getId());
            }
            for (ExpressPrintTemplateSaveDTO expressPrintTemplateSaveDTO : expressPrintTemplateSaveDTOList) {
                Long dataId = expressPrintTemplateSaveDTO.getDataId();
                if (Objects.isNull(dataId) || Objects.equals(0L, dataId)){
                    ExpressPrintTemplateEntity expressPrintTemplateEntity = new ExpressPrintTemplateEntity();
                    expressPrintTemplateEntity.setCorpid(corpid);
                    expressPrintTemplateEntity.setExpressName(expressPrintTemplateSaveDTO.getExpressName());
                    expressPrintTemplateEntity.setExpressCode(expressPrintTemplateSaveDTO.getExpressCode());
                    expressPrintTemplateEntity.setPrintTemplate(expressPrintTemplateSaveDTO.getPrintTemplate());
                    expressPrintTemplateEntity.setTemplateSerial(expressPrintTemplateSaveDTO.getTemplateSerial());
                    expressPrintTemplateEntity.setPaperHeight(expressPrintTemplateSaveDTO.getPaperHeight());
                    expressPrintTemplateEntity.setPaperWidth(expressPrintTemplateSaveDTO.getPaperWidth());
                    expressPrintTemplateEntity.setDefaultTemplate(expressPrintTemplateSaveDTO.getDefaultTemplate());
                    expressPrintTemplateEntity.setCreatorId(userId);
                    expressPrintTemplateEntity.setAddTime(DateTimeUtil.getInt());
                    expressPrintTemplateEntity.setUpdateTime(DateTimeUtil.getInt());
                    expressPrintTemplateEntity.setDel(BasicConstant.ZERO);
                    insertList.add(expressPrintTemplateEntity);
                }else {
                    saveTemplateIdList.add(dataId);
                    ExpressPrintTemplateEntity expressPrintTemplateEntity = new ExpressPrintTemplateEntity();
                    expressPrintTemplateEntity.setId(dataId);
                    expressPrintTemplateEntity.setCorpid(corpid);
                    expressPrintTemplateEntity.setExpressName(expressPrintTemplateSaveDTO.getExpressName());
                    expressPrintTemplateEntity.setExpressCode(expressPrintTemplateSaveDTO.getExpressCode());
                    expressPrintTemplateEntity.setPrintTemplate(expressPrintTemplateSaveDTO.getPrintTemplate());
                    expressPrintTemplateEntity.setTemplateSerial(expressPrintTemplateSaveDTO.getTemplateSerial());
                    expressPrintTemplateEntity.setPaperHeight(expressPrintTemplateSaveDTO.getPaperHeight());
                    expressPrintTemplateEntity.setPaperWidth(expressPrintTemplateSaveDTO.getPaperWidth());
                    expressPrintTemplateEntity.setDefaultTemplate(expressPrintTemplateSaveDTO.getDefaultTemplate());
                    expressPrintTemplateEntity.setCreatorId(userId);
                    expressPrintTemplateEntity.setUpdateTime(DateTimeUtil.getInt());
                    expressPrintTemplateEntity.setDel(BasicConstant.ZERO);
                    updateList.add(expressPrintTemplateEntity);
                }
            }
            databaseIdList.removeAll(saveTemplateIdList);
            if(!databaseIdList.isEmpty()){
                expressPrintTemplateModel.updateBatchDel(databaseIdList,corpid);
            }
            if (!insertList.isEmpty()){
                expressPrintTemplateModel.insertBatch(insertList);
            }
            if (!updateList.isEmpty()){
                expressPrintTemplateModel.updateBatch(updateList,corpid);
            }
        }

        //打印机信息的编辑保存
        if (Objects.nonNull(printerSaveDTOList)){
            List<PrinterEntity> insertList = new ArrayList<>();
            List<PrinterEntity> updateList = new ArrayList<>();
            //该公司下已有的打印机信息
            List<PrinterEntity> entities = printerModel.findEntities(param);
            List<Long> printerIdList = new ArrayList<>();
            List<Long> savePrinterIdList = new ArrayList<>();
            for (PrinterEntity entity : entities) {
                printerIdList.add(entity.getId());
            }
            for (PrinterSaveDTO printerSaveDTO : printerSaveDTOList) {
                Long dataId = printerSaveDTO.getDataId();
                if (Objects.isNull(dataId) || Objects.equals(0L, dataId)){
                    PrinterEntity printerEntity = new PrinterEntity();
                    printerEntity.setCorpid(corpid);
                    printerEntity.setCreatorId(userId);
                    printerEntity.setDel(BasicConstant.ZERO);
                    printerEntity.setAddTime(DateTimeUtil.getInt());
                    printerEntity.setUpdateTime(DateTimeUtil.getInt());
                    printerEntity.setPrinterName(printerSaveDTO.getPrinterName());
                    printerEntity.setPrinterCode(printerSaveDTO.getPrinterCode());
                    printerEntity.setDefaultPrinter(printerSaveDTO.getDefaultPrinter());
                    insertList.add(printerEntity);
                }else{
                    savePrinterIdList.add(dataId);
                    PrinterEntity printerEntity = new PrinterEntity();
                    printerEntity.setId(dataId);
                    printerEntity.setCorpid(corpid);
                    printerEntity.setCreatorId(userId);
                    printerEntity.setDel(BasicConstant.ZERO);
                    printerEntity.setUpdateTime(DateTimeUtil.getInt());
                    printerEntity.setPrinterName(printerSaveDTO.getPrinterName());
                    printerEntity.setPrinterCode(printerSaveDTO.getPrinterCode());
                    printerEntity.setDefaultPrinter(printerSaveDTO.getDefaultPrinter());
                    updateList.add(printerEntity);
                }
            }
            printerIdList.removeAll(savePrinterIdList);
            if(!printerIdList.isEmpty()){
                printerModel.updateBatchDel(printerIdList,corpid);
            }
            if (!insertList.isEmpty()){
                printerModel.insertBatch(insertList);
            }
            if (!updateList.isEmpty()){
                printerModel.updateBatch(updateList, corpid);
            }
        }
        // 已选值同步到数据字典中 TODO 可抽取新方法
        if (CollectionsUtil.isNotEmpty(expressInformationSaveDTOList)) {
            Map<String, String> selectMap = new HashMap<>(expressInformationSaveDTOList.size());
            expressInformationSaveDTOList.forEach(item -> selectMap.put(item.getExpressCode(), item.getExpressName()));
            DataDictionaryEntity dataDictionaryEntity = dataDictionaryModel.getByType(DictionaryEnum.EXPRESS_NAME.getType(), corpid);
            if (Objects.isNull(dataDictionaryEntity)) {
                JSONArray insertArr = new JSONArray();
                selectMap.forEach((key, value) -> {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("text", value);
                    jsonObject.put("value", key);
                    jsonObject.put("enable", 1);
                    jsonObject.put("isEdit", 0);
                    insertArr.add(jsonObject);
                });
                DataDictionaryEntity dictionaryEntity = new DataDictionaryEntity();
                dictionaryEntity.setCorpid(corpid);
                dictionaryEntity.setType(DictionaryEnum.EXPRESS_NAME.getType());
                dictionaryEntity.setData(JSON.toJSONString(insertArr));
                dataDictionaryModel.insert(dictionaryEntity);
            } else {
                JSONArray jsonArray = JSON.parseArray(dataDictionaryEntity.getData());
                for (int i = 0; i < jsonArray.size(); i++) {
                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                    selectMap.remove(jsonObject.getString("value"));
                }
                if (!selectMap.isEmpty()) {
                    JSONArray insertArr = new JSONArray();
                    selectMap.forEach((key, value) -> {
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.put("text", value);
                        jsonObject.put("value", key);
                        jsonObject.put("enable", 1);
                        jsonObject.put("isEdit", 0);
                        insertArr.add(jsonObject);
                    });
                    jsonArray.addAll(insertArr);
                    dataDictionaryModel.update(dataDictionaryEntity.getId(), corpid, JSON.toJSONString(jsonArray));
                }
            }
        }
        return new ElectronicExressVO();
    }
}
